package cn.yx.common.core.util.io;

import cn.yx.common.core.constant.message.io.UnzipUtilMessageKey;
import cn.yx.common.core.exception.CommonException;
import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

/**
 * <p>zip解压工具类</p>
 *
 * @author Wgssmart
 */
@Slf4j
public final class UnzipUtil {

    private UnzipUtil() {
    }

    /**
     * 解压指定的zip文件到指定文件（目录）
     *
     * @param zipPath zip文件路径
     * @param toPath  目标文件（目录）
     */
    public static void toFile(String zipPath, String toPath) {
        toFile(new File(zipPath), toPath);
    }

    /**
     * 解压指定的zip文件到指定文件（目录）
     *
     * @param zipFile zip文件对象
     * @param toPath  目标文件（目录）
     */
    public static void toFile(File zipFile, String toPath) {
        FileUtil.mkdirs(toPath);
        try (ZipFile theZipFile = new ZipFile(zipFile)) {
            Enumeration<? extends ZipEntry> zipEntryEnumeration = theZipFile.entries();
            while (zipEntryEnumeration.hasMoreElements()) {
                ZipEntry zipEntry = zipEntryEnumeration.nextElement();
                String filePath = toPath + File.separator + zipEntry.getName();
                if (zipEntry.isDirectory()) {
                    FileUtil.mkdirs(filePath);
                } else {
                    try (InputStream zipInputStream = theZipFile.getInputStream(zipEntry)) {
                        extractFile(zipInputStream, filePath);
                    }
                }
            }
        } catch (IOException e) {
            log.error("unzip to file error: {}, zip file: {}, to path: {}",
                    e.getMessage(), zipFile.getAbsolutePath(), toPath);
            throw new CommonException(UnzipUtilMessageKey.UNZIP_FILE_ERROR, e);
        }
    }

    /**
     * 解压zip条目
     *
     * @param inputStream zip input stream输入流对象
     * @param filePath    解压目标路径
     * @throws IOException IOException
     */
    private static void extractFile(InputStream inputStream, String filePath) throws IOException {
        FileUtil.createNewFile(filePath);
        try (BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(filePath))) {
            IoUtil.toOutput(inputStream, bufferedOutputStream);
        }
    }

}
